//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <bsp.h>
#include <mmu.h>
#include <init.h>

//const uint_t c_uMaxNumberOfModules  = 16;

typedef struct PackageInfo {
    uint32_t        uReserved;
    BootModule      *modules;
    uint_t          uNumberOfModules;
    size_t          uPackageSize;
    char            *szCommandLine;
} PackageInfo;

#if defined(_GNUC)

DECL_LINKERSYMBOL byte_t _ImageBegin;

#define IMAGE_BEGIN     ((offset_t)&_ImageBegin)

#else

#define IMAGE_BEGIN     ((offset_t)0xc0020000)

#endif

STATIC DECL_CODEINIT void GetBootModulesFromPackage(
        PackageInfo *pPackageInfo, offset_t imageOffset);

EXTERN_C DECL_CODEINIT void InitBootModules()
{
    offset_t imageOffset = IMAGE_BEGIN;

    offset_t packageOffset = *(offset_t *)(8 + imageOffset);

    PackageInfo *pPackageInfo = (PackageInfo *)(packageOffset + imageOffset);

    if (NULL != pPackageInfo->szCommandLine) {
        bsp.szBootCommandLine =
            (char *)((offset_t)pPackageInfo->szCommandLine + imageOffset);
    }

    GetBootModulesFromPackage(pPackageInfo, imageOffset);
}

STATIC DECL_CODEINIT void GetBootModulesFromPackage(
                PackageInfo *pPackageInfo, offset_t imageOffset)
{
    bsp.uNumberOfBootModules = pPackageInfo->uNumberOfModules;

//    assert(c_uMaxNumberOfModules >= bsp.uNumberOfBootModules);

    bsp.pBootModules =
        (BootModule *)((offset_t)pPackageInfo->modules + imageOffset);

    bsp.regionOfBootModules.uBasePageNo   = VIRTADDR_TO_PAGENO(imageOffset);
    bsp.regionOfBootModules.uLimitPageNo  = bsp.regionOfBootModules.uBasePageNo
        + NUMBEROF_PAGES(RoundUp2(pPackageInfo->uPackageSize, PAGE_SIZE));

    for (uint_t i = 0; i < bsp.uNumberOfBootModules; i++) {
        bsp.pBootModules[i].region.uBasePageNo  +=
            VIRTADDR_TO_PAGENO(imageOffset);
        bsp.pBootModules[i].region.uLimitPageNo +=
            VIRTADDR_TO_PAGENO(imageOffset);
    }
}
